﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Happy.ExtentionMethods;

namespace Happy.Query
{
    /// <summary>
    /// 查询参数。
    /// </summary>
    public sealed class QueryArgument
    {
        private static readonly QueryArgument _All = new QueryArgument();

        /// <summary>
        /// 构造方法。
        /// </summary>
        public QueryArgument()
        {
            this.Columns = new List<string>();
            this.WhereClauses = new List<WhereClause>();
            this.OrderClauses = new List<string>();
        }

        /// <summary>
        /// 返回的列。
        /// </summary>
        public List<string> Columns { get; set; }

        /// <summary>
        /// Where子句。
        /// </summary>
        public List<WhereClause> WhereClauses { get; set; }

        /// <summary>
        /// Order子句。
        /// </summary>
        public List<string> OrderClauses { get; set; }

        /// <summary>
        /// 未加限制的查询参数。
        /// </summary>
        public static QueryArgument All
        {
            get { return _All; }
        }

        /// <summary>
        /// 工厂方法。
        /// </summary>
        public static QueryArgument Create(string whereClause, object[] whereClauseArguments)
        {
            var query = new QueryArgument();
            query.WhereClauses.Add(WhereClause.Create(whereClause, whereClauseArguments));

            return query;
        }

        /// <summary>
        /// 工厂方法。
        /// </summary>
        public static QueryArgument Create(string whereClause, object[] whereClauseArguments, params string[] orderClauses)
        {
            var query = Create(whereClause, whereClauseArguments);
            query.OrderClauses.AddRange(orderClauses);

            return query;
        }

        /// <summary>
        /// 工厂方法。
        /// </summary>
        public static QueryArgument Create(List<string> columns, string whereClause, object[] whereClauseArguments)
        {
            var query = Create(whereClause, whereClauseArguments);
            query.Columns = columns;

            return query;
        }

        /// <summary>
        /// 工厂方法。
        /// </summary>
        public static QueryArgument Create(List<string> columns, string whereClause, object[] whereClauseArguments, params string[] orderClauses)
        {
            var query = Create(columns, whereClause, whereClauseArguments);
            query.OrderClauses.AddRange(orderClauses);

            return query;
        }

        /// <summary>
        /// 工厂方法。
        /// </summary>
        public static QueryArgument Create(object condition)
        {
            condition.MustNotNull("condition");

            var properties = condition.GetType().GetProperties();
            var whereClause = new StringBuilder();
            var whereClauseArguments = new object[properties.Length];

            for (var i = 0; i < properties.Length; i++)
            {
                if (i != 0)
                {
                    whereClause.Append(" AND ");
                }
                whereClause.AppendFormat("{0} = @{1}", properties[i].Name, i);
                whereClauseArguments[i] = properties[i].GetValue(condition);
            }

            return QueryArgument.Create(whereClause.ToString(), whereClauseArguments);
        }
    }
}
